package com.niit.scala

import scala.io.StdIn

/*
总结：
 1.三引号表达式用来保存大量文本，同时可以保留换行、空格等格式
 2.惰性赋值：当有一些定义的常量数据较大的时候。而这些数据并不是马上加载到JVM内存中，就可以使用惰性赋值提高效率
 3.标识符就是给变量、方法、类起名字的。Scala和Java标识符非常的相似
    命名规则：
        必须由大小英文字母、数字、下划线_、美元符号 任意组成
        数字不能开头
        不能和Scala关键字重名
        最好做到见名知意
    命名规范：
      变量和方法：小驼峰命名。从第二个单词开始每个单词首字母大写。
      类和特质：大驼峰命名。每个单词的首字母都大写
      包：全部小写，多级用.间隔
 4.数据类型
      所有类型都以大写字母开头
      整型使用Int而是Integer
      定义变量可以不写类型，让编译器自动推断
      默认整型是Int,默认浮点型为Double
      Any是所有类型的父类，相当于Java中的Object
    Scala的类型关系
      AnyVal是所有数值类型的父类       AnyRef是所有引用类型的父类
      Unit类似于Java中的void,一般作为返回类型
      Null是所有引用类型的子类，只有一个实例null
      Nothing是所有数据类型的子类，不能创建类型的实例，一般结合异常使用
 5.类型转换
      自动类型转换  大 装 小
      强制类型转换   小 装 大 缺点：损失精度
      值类型和String类型转换
 */
object Base_02 {


  def main(args: Array[String]): Unit = {

    //1.三引号：用来保存大段的文本信息，并且保留其格式
    /*
    var str1 = "盼望着，盼望着，东风来了，春天的脚步近了。" +
      "一切都像刚睡醒的样子，欣欣然张开了眼。山朗润起来了，水涨起来了，太阳的脸红起来了。" +
      "小草偷偷地从土里钻出来，嫩嫩的，绿绿的。园子里，田野里，瞧去，一大片一大片满是的。坐着，躺着，打两个滚，踢几脚球，赛几趟跑，捉几回迷藏。风轻悄悄的，草软绵绵的。"
    var str2 =
      """
        |盼望着，盼望着，东风来了，春天的脚步近了。
        |
        |一切都像刚睡醒的样子，欣欣然张开了眼。山朗润起来了，水涨起来了，太阳的脸红起来了。
        |
        |小草偷偷地从土里钻出来，嫩嫩的，绿绿的。园子里，田野里，瞧去，一大片一大片满是的。坐着，躺着，打两个滚，踢几脚球，赛几趟跑，捉几回迷藏。风轻悄悄的，草软绵绵的。
        |""".stripMargin

    println(str1)
    println("----------")
    println(str2)
     */
    //2.惰性赋值。当使用惰性赋值的使用，该变量用的时候才会加载到内存当中。格式 lazy val 变量 = 值
    /*
    lazy val a = "张三"
    println(a)
     */

    //3.1数值转换类型  自动转换：用大的数据类型去装小的数据类型
    //从小 到 大 的数据类型依次为： Byte--Short--Int--Long--Float--Double
    var a:Int  = 10
    var b:Long = a
    var c:Double = b + 3.1415926
    println(a,b,c)
    //3.2强制数据类型转换 用 小的 装 大的。缺点：损失精度
    // var/val 变量名:数据类型 = 值.toXxx (Xxx:要转换的类型)
    var d:Double = 5.21
    var e:Int = d.toInt
    println(e)
    //3.3数值类型和String类型之间的转换
    //方式一 任意类型对字符串进行拼接，最终的类型为字符串
    var f:String = 3.14 + ""
    //方式二： 值.toString
    var g:String = 999.toString
    //3.4字符串类型 转成为 值类型
    val h:String = "100"
    val i:Int = h.toInt
    val j:Float = h.toFloat
    println(i,j)
    //问题：布尔类型 能不能转成 数值类型  :不能，Boolean无法转换为值类型
    val l:Boolean = true
    //val m:Int = l.toInt

    //4.余数
    var q = 27 % 5 //背后运算逻辑：27 - 27/5 *5  =27 -25
    println(q)

    //5.键盘录入
    /*
        字符串的键盘录入：StdIn.readLine()
        数值的键盘录入：StdIn.readXxx()  (Xxx:数值的类型)
     */
  /*  println("请输入今年最大的愿望：")
    val str = StdIn.readLine()
    println(s"我的最大的愿望：${str}")*/

    //6.逻辑运算符  &&  ||  ！
    println( 1 > 2 && 2 > 1) //false  &&:两者都成立才成立，只有一个成立也是不成立
    println( 1 > 2 || 2 > 1)//true   ||:两者有一个成立就成立
    println( !(1 > 2) && 2 > 1) //true

    //7.if -else if - else
    /*
    println("请录入成绩：")
    var score = StdIn.readInt()
    if(score >=90 && score<=100){
      println("你很优秀")
    }else if(score>=80 && score<90){
      println("一般般")
    }else if(score>=0 && score<80){
      println("还需努力")
    }else{
      println("成绩无效")
    }*/

    //8.int a = 2 > 1 ? 1 : 0 三目(元)运算符。Scala是没有三目。替代方案就是用if-esle简写方式
    println( if(2>1) 1 else 0 )

    //9.块表达式  { 代码 }  val a = { 代码 }
    val kuai ={
      1+1
      3+3 //最后一条语句 才是最后的返回值
      if(2>1){
        println("成立")
      }
    }
    println(kuai)// 2 ? 6 ?  1：kuai是否还是6 返回值是() 空元组   2：成立会不会输出  会

    //10 for 循环
    //格式： for(i <- 表达式/集合)
    //需求：输出10次 Hello Scala
    for(i <- 1 to 10){ //1 to 10 [1,10]
      println("Hello Scala")
    }

    //11.for循环的守卫  for表达式中，可以添加if判断语句，这个if判断就称之为守卫、
    for( i <- 1 to 10 if i % 2 == 0 ){
      println(i)
    }

    //12.for推导式 for循环也是有返回值的。可以使用yield对for循环进行范围内一个集合
    val v = for (i <- 1 to 10) yield i * 10
    println(v)

    //13 while  do-while
    //需求 输出1-10
    var count = 1
   /* while (count<=10){
      print(count)
      count += 1
    }*/
    /*do {
      print(count)
      count += 1
    }while(count<=10)*/

    //14.break 和 continue  ----> Scala中要想使用break 需要再for循环外面套一层breakable。Scala中没有continue关键字
    import scala.util.control.Breaks.{break,breakable} //需要手动的导入 break breakable
    //1-10的循环 当输出为5的时候 就结束循环
    breakable{
      for (i <- 1 to 10){
        if(i==5){
          break()
        }else{
          println(i)
        }
      }
    }
   //Scala中没有continue关键字 但是可以用 breakable + break
    //输出 1-10的数字，跳过5
    for (i <- 1 to 10){
      breakable{
        if(i==5){
          break()
        }else{
          println(i)
        }
      }

    }

    //15.方法
    /*
       def 方法名(参数名:参数类型,参数名:参数类型):[return Type]={
          方法体
       }
      代码的运行顺序 从上到下 从左到右 从括号里到括号外
     */
                // 20  实参
    println(  getMax(10,20)   )
    //带名参数：在传入实参的时候指定给哪个形参传数据
    println(  getMax(b = 10, a = 20)   )

    println(  getMax2(40,30)   )

    println( getSum(1,2,3,4,5,6,7,8,9,10))
  }
            //形参
  //关于方法中的方法体只有一句话 可以进行优化
  def getMax(a:Int,b:Int):Int={
//   val res =  if (a>b) a else b
//    res
  if (a>b) a else b //这句话会自带返回值 不是 a 就是 b
}
  //优化写法
          //默认参数，直接在形参上定义真实数据。如果没有实参传入的话，那么a,b默认6，7
  def getMax2(a:Int=6,b:Int=7) = if (a>b) a else b

  //变长参数：参数是不固定，可以将方法的参数定义为变长参数
  def getSum(a:Int*)=a.sum

}
